<?php
error_reporting(0);
$folder = './clients/RagexeRE'; // folder containing clients

/*
DROP TABLE IF EXISTS `diff_patcher`;
CREATE TABLE `diff_patcher` (
  `id` MEDIUMINT(9) UNSIGNED NOT NULL AUTO_INCREMENT,
  `download_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `ip` VARCHAR(15) NOT NULL DEFAULT '',
  `client` VARCHAR(25) NOT NULL DEFAULT '',
  `window_title` VARCHAR(32) NOT NULL DEFAULT '',
  `filename` VARCHAR(32) NOT NULL DEFAULT '',
  `font` VARCHAR(32) NOT NULL DEFAULT '',
  PRIMARY KEY  (`id`)
) ENGINE=MYISAM AUTO_INCREMENT=1 ;
*/

//===============================================
// List Clients to choose from
//===============================================

if (!isset($_GET['client'])) {
	echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\">

<head>
<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />
<link href=\"./favicon.ico\" rel=\"shortcut icon\" type=\"image/x-icon\" />
<title>Diff Patcher</title>

<script type=\"text/javascript\">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-16687257-8']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
</script>

</head>

<body>\n";
if ($_SERVER['HTTP_HOST']!='rathena.sourceforge.net') echo "<font color=\"#FF0000\">This is a mirror of <a href=\"http://rathena.sourceforge.net/tools/diff_patcher.php\">http://rathena.sourceforge.net/tools/diff_patcher.php</a></font>\n";
echo "<h2>Choose a client date:</h2>
<h4>for more info, see <a href=\"http://svn6.assembla.com/svn/ClientSide/Diff_Project/Readme.txt\" target=\"_blank\">README.txt</a></h4>\n";
	
	$files1 = scandir($folder);
	foreach ($files1 as $key => $filename1) {
		// skip current and parent folders
		if (in_array($filename1, array('..','.'))) continue;
		
		if (is_dir("$folder/$filename1") && preg_match('/^([0-9]{4}-[0-1][0-9]-[0-3][0-9])$/',$filename1)) {
			// check if DIFF and EXE exist
			$files2 = scandir("$folder/$filename1");
			foreach ($files2 as $key2 => $filename2) {
				$file_info = pathinfo($filename2);
				$filename2 = $file_info['filename'];
				if ($file_info['extension'] == 'diff' && file_exists("$folder/$filename1/$filename2" . '.exe')) {
					echo sprintf("%s / <a href=\"./%s?client=%s\">%s</a><br />\n", $filename1, 
					     // preg_match('/^.*aRagexeRE$/', $filename2) ? $filename1 : "<span style='color:#BFBFBF'>$filename1</span>", 
					     preg_replace('/.*\/([^\/]*)/', '$1', __FILE__), $filename2, $filename2);
				}
			}
		}
	}
	
	if (preg_match('/^([a-zA-Z0-9_-]*)\.sourceforge\.net$/', $_SERVER['HTTP_HOST'])) echo "<address style=\"text-align: right;\">Hosted by <a href=\"http://sourceforge.net/projects/rathena/\" target=\"_blank\"><img src=\"http://sflogo.sourceforge.net/sflogo.php?group_id=637719&amp;type=10\" width=\"80\" height=\"15\" alt=\"SourceForge.net\" border=\"0\" /></a></address>\n";
	echo "</body></html>\n";
	exit(0);
}



//===============================================
// Load Diff Options
//===============================================
/*
[1] => (array)
		[name]  => byte_[Fix]_Aura_Crashfix
		[type]  => 
		[group] => 0
		[byte]  => (array)
					[offset] => before:after
					[199E58] => 117:144
					[199E59] => 41:144
*/

$option_names = array();
$options = array();
$offset_special = array();
$client = $_GET['client'];


preg_match('/^([0-9]{4}-[0-1][0-9]-[0-3][0-9])[a-f]?RagexeRE$/', $client, $date)
	or die('Client not found');

$fp = fopen("$folder/$date[1]/$client" . '.diff', "r")
	or die('I/O error');


while ($line = fgets($fp, 1024)) {
	// skip comments and blank lines
	if (($line[0] == '/' && $line[1] == '/') || $line[0] == "\0" || $line[0] == "\n" || $line[0] == "\r")
		continue;
	
	$part = explode(':', trim($line));
	
	switch ($part[0]) {
	case 'OCRC':
		$OCRC = $part[1];
		break;
	case 'BLURB':
		$BLURB = $part[1];
		break;
	default:
		if (preg_match('/byte_\[([a-zA-Z]+)\](\(([0-9A-Z]+)\))?_(.*)/', $part[0], $args)) {
			if (!in_array($args[4], $option_names)) {
				// new option, add to array
				$option_names[] = $args[4];
				$options[] = array(
					'name'  => $args[4],
					'type'  => $args[1],
					'group' => $args[3],
					'byte'  => array($part[1] => "$part[2]:$part[3]")
				);
				// check for special offsets
				if (strpos($args[4],'Use_Custom_Font') !== false && strlen($part[1]) <= 3 && $part[2] == 0) {
					$offset_special['font'] = $part[1];
				} else if (strpos($args[4],'Custom_Window_Title') !== false && strlen($part[1]) <= 3 && $part[2] == 0) {
					$offset_special['window_title'] = $part[1];
				}
			} else {
				// just append bytes
				$options[array_search($args[4], $option_names)]['byte'][$part[1]] = "$part[2]:$part[3]";
			}
		}
	}
}
fclose($fp);

// header("Content-Type: text/plain");
// echo '$OCRC = ' . $OCRC . "\n";
// echo '$BLURB = ' . $BLURB . "\n";
// echo "\n";
// print_r($option_names);
// print_r($options);
// exit(0);



//===============================================
// Download Client
// http://svn2.assembla.com/svn/Diffgen/DiffGen/Core/Main.php
//===============================================

if (isset($_POST['download'])) {
	// load the DEFAULT exe
	$client_new = file_get_contents("$folder/$date[1]/$client" . '.exe');
	
	if (isset($OCRC) && $OCRC != substr(hexdec(sprintf("%x",crc32($client_new))), -8))
		die ('OCRC mismatch');
	
	$filename = trim(preg_replace("/[^a-zA-Z0-9 ._-]/", "", $_POST['filename']));
	if (!preg_match('/^(.*)\.exe$/', $filename)) $filename = $filename . '.exe';
	
	// only allow a-z A-Z, trim trailing space
	$window_title = trim($_POST['window_title']);
	$font = trim(preg_replace("/[^a-zA-Z ]/", "", $_POST['font']));
	$dataini = trim($_POST['dataini']);
	$clientinfo = trim($_POST['clientinfo']);
	// $clientinfo = trim(preg_replace("/[^a-zA-Z0-9 \/._- ]/", "", $_POST['clientinfo']));
	
	// auto-enable some options if they customized them
	if ($window_title != ($client . ' by Diff Team'))
		$_POST['Custom_Window_Title_(Recommended)'] = 'Custom_Window_Title_(Recommended)';
	if ($font != 'Arial')
		$_POST['9'] = 'Use_Custom_Font';
	if ($dataini != 'DATA.INI')
		$_POST['7'] = 'Enable_Multiple_GRFs';
	
	// apply selected diff patches
	foreach ($option_names as $key => $value) {
		if (in_array($value, $_POST)) {
			foreach ($options[$key]['byte'] as $offset => $bytes) {
				list($before, $after) = explode(':', $bytes);
				$client_new[hexdec($offset)] = chr($after);
			}
		}
	}
	
	// check for special offsets
	$offset_special['dataini']    = dechex(strpos($client_new, 'DATA.INI'));
	$offset_special['clientinfo'] = dechex(strpos($client_new, 'clientinfo.xml'));
	
	// header("Content-Type: text/plain");
	// print_r($offset_special);
	// die();
	
	// additional customizations                                                                 dec offset,                              length
	if (in_array('Custom_Window_Title_(Recommended)', $_POST) && $window_title)
		$client_new = substr_replace($client_new, str_pad($window_title, 32, chr(hexdec(0x00))), hexdec($offset_special['window_title']), 32);
	if (in_array('Use_Custom_Font', $_POST) && $font)
		$client_new = substr_replace($client_new, str_pad($font,         32, chr(hexdec(0x00))), hexdec($offset_special['font'])        , 32);
	if (in_array('Enable_Multiple_GRFs', $_POST) && $dataini)
		$client_new = substr_replace($client_new, str_pad($dataini,       8, chr(hexdec(0x00))), hexdec($offset_special['dataini'])     ,  8);
	if ($clientinfo)
		$client_new = substr_replace($client_new, str_pad($clientinfo,   14, chr(hexdec(0x00))), hexdec($offset_special['clientinfo'])  , 14);
	
	$mysqli = new mysqli('MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_DATABASE');
	$mysqli->query(sprintf("INSERT INTO `diff_patcher` (`download_time`,`ip`,`client`,`window_title`,`filename`,`font`) VALUES (NOW(), '%s', '%s', '%s', '%s', '%s')", 
	               $mysqli->real_escape_string($_SERVER['HTTP_X_REMOTE_ADDR']), $mysqli->real_escape_string($client), $mysqli->real_escape_string($window_title), $mysqli->real_escape_string($filename), $mysqli->real_escape_string($font)));
	$mysqli->close();
	
	// send file for browser to download
	header("pragma: nocache");
	header("Content-Type: application/octet-stream");
	header('Content-Length: '. strlen($client_new)); 
	header('Content-Disposition: attachment; filename="' . $filename . '"'); 
	
	echo $client_new;
	exit(0);
}



//===============================================
// Display Diff Options
//===============================================
echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"
\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">
<html xmlns=\"http://www.w3.org/1999/xhtml\">

<head>
<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\" />
<link href=\"./favicon.ico\" rel=\"shortcut icon\" type=\"image/x-icon\" />
<title>Diff Patcher</title>

<script type=\"text/javascript\">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-16687257-8']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
</script>

</head>

<body>
<h2>$BLURB</h2>\n";
?>

<form action="" method="post">
<table style="width: 100%">
	<tr>
		<td style="width: 200px">Filename (to Save As):</td>
		<td><input name="filename" type="text" maxlength="32" size="32" value="<?php echo $client . '_patched.exe'; ?>" /></td>
	</tr>
	<tr>
		<td style="width: 200px">Custom Window Title:</td>
		<td><input name="window_title" type="text" maxlength="32" size="32" value="<?php echo $client . ' by Diff Team'; ?>" /></td>
	</tr>
	<tr>
		<td style="width: 200px">Font Name:</td>
		<td><input name="font" type="text" maxlength="32" size="32" value="Arial" /></td>
	</tr>
	<tr>
		<td style="width: 200px">DATA.INI</td>
		<td><input name="dataini" type="text" maxlength="8" size="32" value="DATA.INI" /></td>
	</tr>
	<tr>
		<td style="width: 200px">clientinfo.xml</td>
		<td><input name="clientinfo" type="text" maxlength="14" size="32" value="clientinfo.xml" /></td>
	</tr>
<!--
	<tr>
		<td style="width: 200px">&nbsp;</td>
		<td>&nbsp;</td>
	</tr>
	
	<tr>
		<td style="width: 200px">Open/Public and @main Chat</td>
		<td><input name="Other_Chat_Color" type="text" maxlength="6" size="6" value="FFFFFF" /></td>
	</tr>
	<tr>
		<td style="width: 200px">Your Chat</td>
		<td><input name="Your_Chat_Color" type="text" maxlength="6" size="6" value="00FF00" /></td>
	</tr>
	<tr>
		<td style="width: 200px">Your Party Chat</td>
		<td><input name="Your_Party_Chat_Color" type="text" maxlength="6" size="6" value="FFC800" /></td>
	</tr>
	<tr>
		<td style="width: 200px">Other Party Chat</td>
		<td><input name="Other_Party_Chat_Color" type="text" maxlength="6" size="6" value="FFC8C8" /></td>
	</tr>
	<tr>
		<td style="width: 200px">Guild Chat</td>
		<td><input name="Guild_Chat_Color" type="text" maxlength="6" size="6" value="B4FFB4" /></td>
	</tr>
-->
</table><br />

<?php
foreach ($option_names as $key => $value) {
	if ($options[$key]['group']) {
		// group
		echo sprintf("<input type=\"radio\" name=\"%s\" value=\"%s\"%s />%s<br />\n", 
		             $options[$key]['group'], htmlspecialchars($value), (preg_match('/^.*_\(Recommended\)$/', $value) ? ' checked="checked"' : ''), str_replace('_', ' ', htmlspecialchars($value)));
		if (preg_match('/^.*_\(Recommended\)$/', $value)) $group_has_checked = true;
	} else {
		// yes/no
		echo sprintf("<input type=\"checkbox\" name=\"%s\" value=\"%s\"%s />%s<br />\n", 
		             htmlspecialchars($value), htmlspecialchars($value), (preg_match('/^.*_\(Recommended\)$/', $value) ? ' checked="checked"' : ''), str_replace('_', ' ', htmlspecialchars($value)));
	}
	
	// skip line between groups
	if ($key < (count($options)-1) && $options[$key+1]['group'] != $options[$key]['group']) {
		if ($options[$key]['group'])
			echo sprintf("<input type=\"radio\" name=\"%s\" value=\"null\"%s />Default/None<br />\n", $options[$key]['group'], ($group_has_checked ? '' : ' checked="checked"'));
		$group_has_checked = false; // reset "Does this group have a default checked option?"
		echo "<br />\n";
	}
}

echo "<br />\n" . 
     "<input name=\"download\" type=\"submit\" value=\"Download\" />\n" . 
     "</form>\n\n";

// check for Failed patches
if (file_exists("$folder/$date[1]/$client" . ' Failed.txt')) {
	$fail = file("$folder/$date[1]/$client" . ' Failed.txt');
	echo "<h3>Failed Patches (disabled)</h3>\n";
	echo "<span style='color:#FF0000'>\n";
	foreach ($fail as $key => $value) {
		echo htmlspecialchars(trim($value)) . "<br />\n";
	}
	echo "</span>\n\n";
}

if (preg_match('/^([a-zA-Z0-9_-]*)\.sourceforge\.net$/', $_SERVER['HTTP_HOST'])) echo "<address style=\"text-align: right;\">Hosted by <a href=\"http://sourceforge.net/projects/rathena/\" target=\"_blank\"><img src=\"http://sflogo.sourceforge.net/sflogo.php?group_id=637719&amp;type=10\" width=\"80\" height=\"15\" alt=\"SourceForge.net\" border=\"0\" /></a></address>\n";
echo "</body></html>\n";

exit(0);
?>
